#include "textmenu.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "stdio.h"
#include "horse_anim.h"


u8g2_t u8g2;
textMenu_t textMenu;

static void blink(pTextMenu_t pTextMenu);
static void ledoff(pTextMenu_t pTextMenu);
static void ledon(pTextMenu_t pTextMenu);
static void backLightBrightness(pTextMenu_t pTextMenu);
static void Test(pTextMenu_t pTextMenu);
static void BootAnimation(pTextMenu_t pTextMenu);


const char *menuItems[MAX_MENU] = {
    "1.Blink",
    "2.LED OFF",
    "3.LED ON",
    "4.Brightness",
    "5.Test",
    "6.BootAnimation",
};

void (*pSelectFuncCB[MAX_MENU])(pTextMenu_t pTextMenu) = {
    blink,
    ledoff,
    ledon,
    backLightBrightness,
    Test,
    BootAnimation,
};

static unsigned char textMenu_KeyDownCheck(void)
{
    return Key_Scan(KEY_DOWN_PORT, KEY_DOWN_PIN);
}
static unsigned char textMenu_KeyDownCallback(void)
{
    textMenu.curMenuID++;
    if (textMenu.curMenuID >= (MAX_MENU - 1)) {
        textMenu.curMenuID = (MAX_MENU - 1);
    }

    return 1;
}

static unsigned char textMenu_KeyUpCheck(void)
{
    return Key_Scan(KEY_UP_PORT, KEY_UP_PIN);
}
static unsigned char textMenu_KeyUpCallback(void)
{
    textMenu.curMenuID--;
    if (textMenu.curMenuID < 0) {
        textMenu.curMenuID = 0;
    }

    return 1;
}

static unsigned char textMenu_KeyLeftCheck(void)
{
    return Key_Scan(KEY_LEFT_PORT, KEY_LEFT_PIN);
}
static unsigned char textMenu_KeyLeftCallback(void)
{
    return 1;
}

static unsigned char textMenu_KeyRightCheck(void)
{
    return Key_Scan(KEY_RIGHT_PORT, KEY_RIGHT_PIN);
}
static unsigned char textMenu_KeyRightCallback(void)
{
    return 1;
}

static unsigned char textMenu_KeySelectCheck(void)
{
    return Key_Scan(KEY_SELECT_PORT, KEY_SELECT_PIN);
}

static void blink(pTextMenu_t pTextMenu)
{
    while (1) {
        LED1_TOGGLE;
        delay_ms(500);

        if (pTextMenu->KeyRightCheck()) {
            break;
        }
    }
}

static void ledoff(pTextMenu_t pTextMenu)
{
    LED1_OFF;
    delay_ms(500);
}

static void ledon(pTextMenu_t pTextMenu)
{
    LED1_ON;
    delay_ms(500);
}

static void backLightBrightness(pTextMenu_t pTextMenu)
{
    unsigned char brightness = 100;
    char strOut[50] = {0};

    u8g2_ClearBuffer(&u8g2);
    while (1) {
        if (textMenu.KeyDownCheck()) {
            brightness -= 5;
            if (brightness < 0)
                brightness = 0;
            delay_ms(200);
        }

        if (textMenu.KeyUpCheck()) {
            brightness += 5;
            if (brightness > 100)
                brightness = 100;
            delay_ms(200);
        }

        OLED_ScreenSetBrightnessPercentage(brightness);
        sprintf(strOut, "Brightness: %d", brightness);
        u8g2_DrawStr(&u8g2, 15, 35, (const char *)strOut);
        u8g2_SendBuffer(&u8g2);
        u8g2_ClearBuffer(&u8g2);

        if (pTextMenu->KeyRightCheck()) {
            break;
        }
    }
    delay_ms(1000);
}

static void Test(pTextMenu_t pTextMenu)
{
    static uint8_t t;

    while (1) {
        delay_ms(100);
        u8g2_ClearBuffer(&u8g2);
        if (++t >= 32)
            t = 1;
        u8g2_DrawCircle(&u8g2, 64, 32, t, U8G2_DRAW_ALL);
        u8g2_DrawCircle(&u8g2, 32, 32, t, U8G2_DRAW_ALL);
        u8g2_DrawCircle(&u8g2, 96, 32, t, U8G2_DRAW_ALL);
        u8g2_SendBuffer(&u8g2);

        if (pTextMenu->KeyRightCheck()) {
            break;
        }
    }
}

static void BootAnimation(pTextMenu_t pTextMenu)
{
    unsigned char index = 0;

    while (1) {
        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse1);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse2);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse3);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse4);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse5);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse6);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse7);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse8);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse9);
        u8g2_SendBuffer(&u8g2);

        u8g2_ClearBuffer(&u8g2);
        u8g2_DrawBitmap(&u8g2, 0, 0, (128 / 8), 128, horse10);
        u8g2_SendBuffer(&u8g2);

        if (pTextMenu->KeyRightCheck()) {
            break;
        }
    }
}




void TestLines(uint8_t color)
{
    unsigned char x1, y1, x2, y2;

    u8g2_ClearBuffer(&u8g2);

    x1 = y1 = 0;
    y2    = OLED_HEIGHT - 1;
    for (x2 = 0; x2 < OLED_WIDTH; x2 += 6) {
        u8g2_DrawPixel(&u8g2, u8g2_uint_t x, u8g2_uint_t y);
        u8g2_DrawLine(&u8g2,,  x1,  y1,  x2,  y2);
        delay_ms(1);
        u8g2_SendBuffer(&u8g2);
    }
    x2    = SSD1306_WIDTH - 1;
    for (y2 = 0; y2 < SSD1306_HEIGHT; y2 += 6) {
        SSD1306_DrawLine(x1, y1, x2, y2, color);
        HAL_Delay(1);
        SSD1306_UpdateScreen();
    }

    HAL_Delay(10);


    SSD1306_Clear();

    x1    = SSD1306_WIDTH - 1;
    y1    = 0;
    y2    = SSD1306_HEIGHT - 1;
    for (x2 = 0; x2 < SSD1306_WIDTH; x2 += 6) {
        SSD1306_DrawLine(x1, y1, x2, y2, color);
        SSD1306_UpdateScreen();
        HAL_Delay(1);
    }
    x2    = 0;
    for (y2 = 0; y2 < SSD1306_HEIGHT; y2 += 6) {
        SSD1306_DrawLine(x1, y1, x2, y2, color);
        SSD1306_UpdateScreen();
        HAL_Delay(1);
    }

    HAL_Delay(10);


    SSD1306_Clear();

    x1    = 0;
    y1    = SSD1306_HEIGHT - 1;
    y2    = 0;
    for (x2 = 0; x2 < SSD1306_WIDTH; x2 += 6) {
        SSD1306_DrawLine(x1, y1, x2, y2, color);
        HAL_Delay(1);
        SSD1306_UpdateScreen();
    }
    x2    = SSD1306_WIDTH - 1;
    for (y2 = 0; y2 < SSD1306_HEIGHT; y2 += 6) {
        SSD1306_DrawLine(x1, y1, x2, y2, color);
        HAL_Delay(1);
        SSD1306_UpdateScreen();
    }

    HAL_Delay(10);


    SSD1306_Clear();

    x1    = SSD1306_WIDTH - 1;
    y1    = SSD1306_HEIGHT - 1;
    y2    = 0;
    for (x2 = 0; x2 < SSD1306_WIDTH; x2 += 6) {
        SSD1306_DrawLine(x1, y1, x2, y2, color);
        HAL_Delay(1);
        SSD1306_UpdateScreen();
    }
    x2    = 0;
    for (y2 = 0; y2 < SSD1306_HEIGHT; y2 += 6) {
        SSD1306_DrawLine(x1, y1, x2, y2, color);
        HAL_Delay(1);
        SSD1306_UpdateScreen();
    }
}


void TestRectangles(uint8_t color)
{
    uint8_t n, i, i2;

    SSD1306_Clear();

    n = min(SSD1306_WIDTH, SSD1306_HEIGHT);

    for (i = 2; i < n; i += 6) {
        i2 = i / 2;
        SSD1306_DrawRectangle((SSD1306_WIDTH / 2) - i2, (SSD1306_HEIGHT / 2) - i2, i, i, color);
        SSD1306_UpdateScreen();
        HAL_Delay(10);
    }
}

void TestFilledRectangles(uint8_t color)
{
    uint8_t n, i, i2,
            cx = SSD1306_WIDTH / 2 - 1,
            cy = SSD1306_HEIGHT / 2 - 1;

    SSD1306_Clear();

    n = min(SSD1306_WIDTH, SSD1306_HEIGHT);
    for (i = n; i > 0; i -= 6) {
        i2    = i / 2;
        SSD1306_DrawFilledRectangle(cx - i2, cy - i2, i, i, color);
        SSD1306_UpdateScreen();
        HAL_Delay(10);
    }
}

void TestFilledCircles(uint8_t radius, uint16_t color)
{
    uint8_t x, y, w = SSD1306_WIDTH, h = SSD1306_HEIGHT, r2 = radius * 2;

    SSD1306_Clear();

    for (x = radius; x < w; x += r2) {
        for (y = radius; y < h; y += r2) {
            SSD1306_DrawFilledCircle(x, y, radius, color);
            SSD1306_UpdateScreen();
            HAL_Delay(10);
        }
    }
}

void TestCircles(uint8_t radius, uint16_t color)
{
    SSD1306_Clear();

    uint8_t x, y, r2 = radius * 2,
                  w = SSD1306_WIDTH + radius,
                  h = SSD1306_HEIGHT + radius;

    for (x = 0; x < w; x += r2) {
        for (y = 0; y < h; y += r2) {
            SSD1306_DrawCircle(x, y, radius, color);
            SSD1306_UpdateScreen();
            HAL_Delay(10);
        }
    }
}

void TestTriangles(uint8_t color)
{
    uint8_t n, i, cx = SSD1306_WIDTH  / 2 - 1,
                  cy = SSD1306_HEIGHT / 2 - 1;

    SSD1306_Clear();

    n = min(cx, cy);
    for (i = 0; i < n; i += 5) {
        SSD1306_DrawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, color);
        SSD1306_UpdateScreen();
        HAL_Delay(10);
    }

}

























void textMenu_Init(pTextMenu_t pTextMenu)
{
    unsigned char menuItem_index = 0;

    for (menuItem_index = 0; menuItem_index < MAX_MENU; menuItem_index++) {
        pTextMenu->pTmenuList[menuItem_index] = menuItems[menuItem_index];
    }

    pTextMenu->textMenuSize     = (sizeof(menuItems) / sizeof(menuItems[0]));
    pTextMenu->curMenuID        = 0;
    pTextMenu->KeyDownCheck     = textMenu_KeyDownCheck;
    pTextMenu->KeyDownCallback  = textMenu_KeyDownCallback;
    pTextMenu->KeyUpCheck       = textMenu_KeyUpCheck;
    pTextMenu->KeyUpCallback    = textMenu_KeyUpCallback;
    pTextMenu->KeyLeftCheck     = textMenu_KeyLeftCheck;
    pTextMenu->KeyLeftCallback  = textMenu_KeyLeftCallback;
    pTextMenu->KeyRightCheck    = textMenu_KeyRightCheck;
    pTextMenu->KeyRightCallback = textMenu_KeyRightCallback;
    pTextMenu->KeySelectCheck   = textMenu_KeySelectCheck;

    for (menuItem_index = 0; menuItem_index < MAX_MENU; menuItem_index++) {
        pTextMenu->KeySelectCallback[menuItem_index] = pSelectFuncCB[menuItem_index];
    }
}


void textMenu_Handle(pTextMenu_t pTextMenu)
{
    unsigned char tMenu_index = 0;

    if (pTextMenu->KeyDownCheck()) {
        pTextMenu->KeyDownCallback();
    }

    if (pTextMenu->KeyUpCheck()) {
        pTextMenu->KeyUpCallback();
    }

    if (pTextMenu->KeySelectCheck()) {
        pTextMenu->KeySelectCallback[pTextMenu->curMenuID](pTextMenu);
    }

    for (tMenu_index = 0; tMenu_index <= MAX_MENU; tMenu_index++) {
        if (textMenu.curMenuID < MENUS_IN_ONEPAGE) {
            if (textMenu.curMenuID == tMenu_index) {
                u8g2_DrawRFrame(&u8g2, 0, tMenu_index * TEXT_HEIGHT, LCD_WIDTH, BOX_HEIGHT, 2);
                u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);
            }
            u8g2_DrawStr(&u8g2, TEXT_WIDTH_OFFSET, TEXT_HEIGHT * tMenu_index + 11, pTextMenu->pTmenuList[tMenu_index]);
        } else {
            if (textMenu.curMenuID == tMenu_index) {
                /* make sure new page menu text alway show at the last */
                u8g2_DrawRFrame(&u8g2, 0, (tMenu_index - (1 + textMenu.curMenuID - MENUS_IN_ONEPAGE)) * TEXT_HEIGHT, LCD_WIDTH,
                                BOX_HEIGHT, 2);
            }
            u8g2_DrawStr(&u8g2, TEXT_WIDTH_OFFSET, (tMenu_index - (1 + textMenu.curMenuID - MENUS_IN_ONEPAGE)) * TEXT_HEIGHT + 11,
                         pTextMenu->pTmenuList[tMenu_index]);
        }
    }

    u8g2_SendBuffer(&u8g2);
    u8g2_ClearBuffer(&u8g2);
}


